package demo4

// 职责链设计模式

// 分析 需要进一批水果，现在有一个地方 里面都是批发水果市场
// 但是每次进水果的时候量不一样，批发水果市场的店能提供的水果量也不一样，那么开始

// 水果批发[批发的动作是抽象的所有使用接口] 量检测 是否满足需求,  如果满足需求则购买上报
// 如果不满足，则让老板娘推荐满足的店面
// 门面[是看得见的所以使用结构体可以实例化] 提供水果批发，提供水果量

type FruitWholesaler interface{
	CheckNumber(PayNumber int) bool
	Buy(Number int)
}

type Facade struct{
	FruitWholesaler
	OtherFacade *Facade
}

// 推荐
func (f *Facade) RecommendOtherFacade(o *Facade){
	f.OtherFacade = o
}

// 校验是否满足需求
func (f *Facade)CheckNumber(PayNumber int) bool{
	return true
}

func (f *Facade)Buy(Number int){
	// 购买
	if CheckNumber(Number){
		f.FruitWholesaler.Buy(Number)
		return
	}
	if f.OtherFacade !=nil{
		f.OtherFacade.FruitWholesaler(Number)
	}
	fmt.Println("数量:",Number)
	fmt.Println("购买中....")
}

type AppleStore struct{
	num  int // 该店面拥有的数量
}

func NewAppleStore() *Facade{
	return &Facade{
		FruitWholesaler:&AppleStore{
			num:100,
		}
	}
}

func (a *AppleStore)CheckNumber(PayNumber int) bool {
	return a.num > PayNumber
}
func (a *AppleStore)Buy(Number){
	fmt.Printf("店面拥有:%d,购买了:%d,还剩:%d\n",a.num,Number,a.num-Number)
}

type JujubeShop struct{
	num int
}
func NewJujubeShop() *Facade{
	return &Facade{
		FruitWholesaler:&JujubeShop{num:500}
	}
}
func (j *JujubeShop)CheckNumber(PayNumber int) bool{
	return j.num > PayNumber
}
func (j *JujubeShop)Buy(Number int){
	// 可以增加限购的条件，比如说一个人买了300 就限购了 ，然后再循环开始购买 
	fmt.Printf("店面拥有:%d,购买了:%d,还剩:%d\n",j.num,Number,j.num-Number)
}

// ------------------------------------------------------------------------

// 访问者设计模式
type Customer interface{
	Accept(Visitor)
}
type Visitor interface{
	Visit(Customer)
}

type CustomerCol struct{
	customers []Customer
}
func (c *CustomerCol)Add(customer Customer){
	c.customers  = appedn(c.customers,customer)
}
func (c *CustomerCol)Accept(visitor Visitor){
	for _, customer := range c.customers{
		visitor.Visit(customer)
	}
}
// 客户拓展
type EnterpriseCustomer struct{
	name string
}

func NewEnterpriseCustomer(name string) *EnterpriseCustomer{
	return &EnterpriseCustomer{
		name:name,
	}
}
func (c *EnterpriseCustomer)Accept(visitor Visitor){
	visitor.Visit(c)
}

// 服务拓展
type ServiceCustomer struct{}
func (s *ServiceCustomer)Visit(customer Customer){
	switch c := customer.(type) {
	case *EnterprisCustomer:
		//-----
	}
}
// ------------------------------------------------------------------------

// 备忘录设计模式
type Memeto interface{}
type Game struct{
	hp,mp int
}

type gameMemeto struct{
	hp,mp int
}

func NewGame(hp ,mp int) *Game{
	return &Game{
		hp:hp,
		mp:mp,
	}
}
func (g *Game)Play(hp,mp int){
	g.hp += hp
	g.mp += mp
}
func (g *Game)Save()*gameMemeto{
	return &gameMemeto{
		hp:g.hp,
		mp:g.mp,
	}
}

func (g *Game)Load(m Memeto){
	m := m.(*gameMemeto)
	g.hp = m.hp
	g.mp = m.mp
}

func (g *Game)Status(){
	fmt.Println(g.hp,g.mp)
}
// 备忘录设计模式: 设计一个空接口来反射是否是需要的数据，然后再定义一个雷同的 结构体来进行备份和还原使用
// ------------------------------------------------------------------------
// 状态设计模式  state
type Week interface{
	Today()
	Next(*DayConext)
}
type DayConext struct{
	Week
}
func NewDayContext() *DayConext{
	return &DayConext{
		Week:&Sunday{},
	}
}
func (d *DayConext)Next(){d.Week.Next(d)}
func (d *DayConext)Today(){d.Week.Today()}

type Sunday struct{}
func (*Sunday)Today(){fmt.Println("sunday")}
func (*Sunday)Next(d *DayConext){d.Week = &Monday{}}

type Monday struct{}
func (*Monday)Today(){fmt.Println("Monday")}
func (*Monday)Next(d *DayConext){d.Week = &Tuesday{}}

type Tuesday struct{}
func (*Tuesday)Today(){fmt.Println("Tuesday")}
func (*Tuesday)Next(d *DayConext){d.Week = &Wednesday{}}
// 状态设计模式:交替执行的逻辑或者命令，可使用该模式来交替的完成
// ------------------------------------------------------------------------
// 解析器设计模式
type Node interface{
	Interper() int
}

type ValNode struct{
	val int
}
func (v *ValNode)Interper() int{ return v.val }

func AddNode struct{
	left,right Node
}
func (a *AddNode)Interper() int { return a.left.Interper() +  a.right.Interper() }

func MidNode struct{
	left,right Node
}
func (a *MidNode) Interper() int {return a.left.Interper() -  a.right.Interper()}

type Parser struct{
	exp []string
	index int
	prev Node
}

func (p *Parser) Parser(exp string){
	p.exp = strings.Split(exp, " ")
	
	for {
		if p.index >= len(p.exp){
			return
		}
		switch  p.exp[p.index]{
		case "+":
			// 
			p.pre = p.newAddNode()
		case "-":
			// 
			p.pre = p.newMidNode()
		default:
			// 
			p.pre = p.newValNode()
		}
	}
}

func (p *Parser)newAddNode() Node{
	p.index++
	return &AddNode{
		left:p.pre,
		right:p.newValNode(),
	}
}

func (p *Parser)newMidNode() Node{
	p.index++
	return &MidNode{
		left:p.pre,
		right:p.newMidNode(),
	}
}

func (p *Parser)newValNode() Node{
	v, _ := strconv.Atoi(p.exp[p.index])
	p.index++
	return &ValNode{
		val:v,
	}

func (p *Parser)GetResult(){
	return p.pre
}
// 解析器设计模式: 主要是将复杂的逻辑分块化成简单的逻辑，然后通过不同的组合完成复杂的逻辑

// ------------------------------------------------------------------------
// 模板设计模式

type Downloader interface{
	Download(uri string)
}

type template struct{
	implement
	uri string
}

type implement interface{
	save()
	down()
}

func NewImplement(impl implement) *template{
	return &template{
		implement:impl,
	}
}

func (i *template)Download(uri string){
	i.uri = uri
	i.implement.down()
	i.implement.save()
}
// 继承
type HttpDownload struct{
	*template
}
func NewHttpDownlaod() Downloader{
	http := new(HttpDownload)
	template := NewImplement(http)
	http.template = template
	return template
}
func (*HttpDownload)save(){
	// 
}
func (*HttpDownload)down(){
	//
}
